home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir30
/
drftls.zip
/
XDOS_DT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-28
|
27KB
|
790 lines
/* XDOS_DT.C
*************************************************
**** THIS SOURCE CODE IS DERIVED FROM XDOS.C ****
**** AND MODIFIED FOR USE WITH DRAFTOOLS. ****
**** FUNCTION NAMES HAVE BEEN PREFIXED WITH ****
**** 'DT_' TO AVOID ANY NAMING CONFLICTS. ****
**** ****
**** Last Revision: 8/29/93 ****
*************************************************
Copyright 1992 Autodesk, Inc.
Permission to use, copy, modify, and distribute this software
for any purpose and without fee is hereby granted, provided
that the above copyright notice appears in all copies and that
both that copyright notice and this permission notice appear in
all supporting documentation.
THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED
WARRANTY. ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR
PURPOSE AND OF MERCHANTABILITY ARE HEREBY DISCLAIMED.
DESCRIPTION:
============
WatCom C/C++ 9.5 protected mode ADS application for use with AutoCAD
Release 12.
Each function returns an ADS error for invalid, too few or too many
arguments. Each function returns nil on failure, unless otherwise
noted.
DT_DOSDIR ------------------------------------------------------------------
Returns a list of file names in the current directory matching a given
wildcard. The values in the list are returned as strings. The mask
argument determines what type(s) of files are returned in the list.
A mask of 0 will return all normal files in the current directory.
Note that this includes *read-only* files.
Other mask arguments can be constructed as a bit-coded integer, using
the following codes:
1: Read-only files
2: Hidden files
4: System files
8: Volume ID
16: Subdirectory
32: Archived
A mask of 1 will return all the normal files and all the read-only files
in the current directory.
Usage: (dt_dosdir wild-card-string integer-mask)
Example: (dt_dosdir "*.dwg" 0)
DT_DOSSUBDIR ---------------------------------------------------------------
Returns a list of sub-directories in the current directory. The values
in the list are returned as strings.
Usage: (dt_dossubdir)
DT_DOSDRV ------------------------------------------------------------------
Returns a list of available drives. The list is integer based, where 1
= Drive A:, 2 = Drive B:, 3 = Drive C:, etc. The list may not be
sequential, i.e., the list (1 2 3 7 8) means that drives A:, B:, C:, G:
and H: are available.
Usage: (dt_dosdrv)
DT_DOSCURDIR ---------------------------------------------------------------
Returns the current directory as a string.
Usage: (dt_doscurdir)
DT_DOSCURDRV ---------------------------------------------------------------
Returns the current drive. The return value is an integer, where 1 =
Drive A:, 2 = Drive B:, 3 = Drive C:, etc.
Usage: (dt_doscurdrv)
DT_DOSSETDIR ---------------------------------------------------------------
Changes the current directory matching a full pathname. The pathname
argument must be a string.
Usage: (dt_dossetdir pathname-string)
Example: (dt_dossetdir "\\r12\\sample")
Example: (dt_dossetdir "/r12/sample")
DT_DOSSETDRV ---------------------------------------------------------------
Changes the current drive. The single required argument must be an
integer, where 1 = Drive A:, 2 = Drive B:, 3 = Drive C:, etc.
Usage: (dt_dossetdrv drive-integer)
Example: (dt_dossetdrv 3) ;set to drive C:
DT_DOSDELETEFILE -----------------------------------------------------------
Deletes a file. The filename argument must be a string, and can
include a full path specification.
The file must be a read/write file; that is, the function will not
delete a file with a read-only attribute set true.
Usage: (dt_dosdeletefile pathname-string)
Example: (dt_dosdeletefile "/work/junk.scr")
DT_DOSRENAME ---------------------------------------------------------------
This function renames one file to another file name. The function takes
two arguments. Each one has to be a file name or path to a file name.
The return value is an integer. A 1 means successful and a 0 means the
call failed.
Usage: (dt_dosrename pathname-string newpathname-string)
(dt_dosrename file-name newfile-name)
Example: (dt_dosrename "C:\\auto.exe" "aaa.exe")
(dt_dosrename "acad.exe" "daca.exe")
*****************************************************************************
* NOTE: Any file name not in current directory will be returned as an *
* error unless the double back slashes are used in the path, as in *
* the above examples. This applies to almost all functions in this *
* file. *
*****************************************************************************
AUTHORS:
Josh Gordon, Autodesk, Inc.
Brad Zehring, Autodesk, Inc.
Jerry A. Schwartz, PlotMasters, Inc.
Jonathan M. Schwartz, Interlake, Inc.
Modified to compile as a protected mode application for WatCom C/C++ 9.5
by:
Owen Wengerd, Manu-Soft Computer Services
P.O. Box 84
Fredericksburg, OH 44627
CompuServe ID: 71324,3252
*/
#include <stdio.h>
#include <dos.h>
#include <io.h>
#include <fcntl.h>
#include <stdlib.h>
#include <adslib.h>
#define MAX_DIR 64
/* Utility definition to get an array's element count (at compile
time). For example:
int arr[] = {1,2,3,4,5};
...
printf("%d", ELEMENTS(arr));
would print a five. ELEMENTS("abc") can also be used to tell how
many bytes are in a string constant INCLUDING THE TRAILING NULL. */
#define ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
/* All the functions that we'll define will be listed in a single table,
together with the internal function that we call to handle each. The
functions all take a single argument (the resbuf that has the
arguments) and return an integer (RTNORM or RTERROR for good or bad
status). */
/* First, define the structure of the table: a string giving the AutoCAD name
of the function, and a pointer to a function returning type int. */
struct func_entry { char *func_name; int (*func) _((struct resbuf *)); };
/* Here we declare the functions that handle the calls. */
int dt_dosdir _((struct resbuf *rb));
int dt_dossubdir _((struct resbuf *rb));
int dt_dosdrv _((struct resbuf *rb));
int dt_doscurdrv _((struct resbuf *rb));
int dt_dossetdrv _((struct resbuf *rb));
int dt_dossetdir _((struct resbuf *rb));
int dt_doscurdir _((struct resbuf *rb));
int dt_dosdeletefile _((struct resbuf *rb));
int dt_dosrename _((struct resbuf *rb));
/* Here we define the array of function names and handlers. */
static struct func_entry func_table[] = { {"dt_dosdir", dt_dosdir},
{"dt_dossubdir", dt_dossubdir},
{"dt_doscurdrv", dt_doscurdrv},
{"dt_dossetdrv", dt_dossetdrv},
{"dt_dosdrv", dt_dosdrv},
{"dt_dossetdir", dt_dossetdir},
{"dt_doscurdir", dt_doscurdir},
{"dt_dosdeletefile", dt_dosdeletefile},
{"dt_dosrename",dt_dosrename},
};
/* To add more functions to this table, just put them in the list, after
declaring the function names. Note that in standard C it's all right to
have a superfluous comma after the last item. */
/* The code from here to the end of dofun() is UNCHANGED when you add or delete
functions. */
/* Declarations of other local functions */
void main _((int, char **));
int dofun _((void));
int funcload _((void));
char *strdup(const char *src);
char *str_tolow(char *string); /* converts string to all lowercase */
char *str_toup(char *string); /* converts string to all uppercase */
/*-----------------------------------------------------------------------*/
/* MAIN - the main routine */
void main(argc,argv)
int argc;
char *argv[];
{
short scode = RSRSLT; /* Normal result code (default) */
int stat;
ads_init(argc, argv); /* Open communication with AutoLISP */
for ( ;; ) { /* Request/Result loop */
if ((stat = ads_link(scode)) < 0) {
printf("XDOS_DT: bad status from ads_link() = %d\n", stat);
fflush(stdout);
exit(1);
}
scode = RSRSLT; /* Reset result code */
switch (stat) {
case RQXLOAD: /* Load & define functions */
scode = funcload() == RTNORM ? RSRSLT : RSERR;
break;
case RQSUBR: /* Handle external function requests */
scode = dofun() == RTNORM ? RSRSLT : RSERR;
break;
default:
break;
}
}
}
/*-----------------------------------------------------------------------*/
/* FUNCLOAD -- Define this application's external functions. Return
RTERROR on error, else RTNORM. */
static int funcload()
{
int i;
for (i = 0; i < ELEMENTS(func_table); i++) {
if (!ads_defun(func_table[i].func_name, i))
return RTERROR;
}
return RTNORM;
}
/*-----------------------------------------------------------------------*/
/* DOFUN -- Execute external function (called upon an RQSUBR request).
Return value from the function executed, RTNORM or RTERROR. */
static int dofun()
{
struct resbuf *rb;
int val;
/* Get the function code and check that it's within range.
(It can't fail to be, but paranoia doesn't hurt.) */
if ((val = ads_getfuncode()) < 0 || val >= ELEMENTS(func_table)) {
ads_fail("Received nonexistent function code.");
return RTERROR;
}
/* Fetch the arguments, if any. */
rb = ads_getargs();
/* Call the handler and return its success-failure status. */
val = (*func_table[val].func)(rb);
ads_relrb(rb);
return val;
}
/* The code from the beginning of main() to here is UNCHANGED when you add or
delete functions. */
/* we need our own strdup... */
char *strdup(const char *src)
{
char *retval = NULL;
/* If the malloc fails, bail out of here because there's something
horribly wrong with memory allocation */
if ((retval = malloc(strlen(src) + 1)) == NULL) {
ads_printf("\nmalloc failed in strdup, XDOS_DT.C");
ads_exit(1);
} else {
strcpy(retval, src);
return retval;
}
}
/* Returns subdirectories under current directory to AutoLISP as a list of
strings.
getargs argument is a pointer to the first result buffer returned by
ads_getargs(). We expect to find no values in the resbuf chain.*/
int dt_dossubdir(getargs)
struct resbuf *getargs;
{
struct resbuf *rb = NULL; /* temp resbuf for loop */
struct find_t c_file; /* MSC file structure */
int retval; /* loop test */
char *wildspec = "*.*"; /* test all files */
unsigned mask = _A_SUBDIR; /* subdirectory mask */
unsigned int fileattrib; /* file attribute */
struct resbuf *retlist, *rettail; /* return list */
if (getargs != NULL) {
ads_printf("\nDT_DOSSUBDIR: Too many arguments.");
return RTERROR;
}
/* Get first filename from current directory */
retval = _dos_findfirst(wildspec, mask, &c_file);
retlist = NULL;
rettail = NULL;
while (retval == 0) {
_dos_getfileattr(c_file.name, &fileattrib); /* get file's attr */
if ((fileattrib & _A_SUBDIR) != 0) { /* directory? */
rb = ads_newrb(RTSTR); /* allocate new resbuf */
if (retlist == NULL) { /* new return list? */
rettail = retlist = rb; /* they're all the same */
} else { /* else, point current tail to */
rettail->rbnext = rb; /* new resbuf and then set tail */
rettail = rb; /* equal to new resbuf */
}
/* store filename in list */
rb->resval.rstring = strdup(c_file.name);
}
retval = _dos_findnext(&c_file); /* get next filename */
}
/* Now set up to return the list */
ads_retlist(retlist);
ads_relrb(retlist);
return RTNORM;
}
/* Returns list of files in current drive and directory to AutoLISP as
a list of strings.
getargs argument is a pointer to the first result buffer returned by
ads_getargs(). We expect to find two values in the resbuf chain: a
string wildcard specification and an integer file attribute mask. */
int dt_dosdir(getargs)
struct resbuf *getargs;
{
struct resbuf *rb = NULL; /* temp resbuf for loop and args */
struct find_t c_file; /* MSC file structure */
int retval; /* loop test */
char *wildspec = NULL; /* initialize wildcard spec */
unsigned mask; /* file mask from user */
struct resbuf *retlist, *rettail; /* return list */
/* Get the arguments passed in with the function */
if (getargs == NULL) {
ads_printf("\nDT_DOSDIR: Expected argument.");
return RTERROR;
}
rb = getargs;
/* Get wildcard specification */
if (rb->restype != RTSTR) {
ads_printf("\nDT_DOSDIR called with a %d type.", rb->restype);
ads_printf("\nExpected a string as first argument.");
return RTERROR;
}
/* Save the value in local */
wildspec = strdup(rb->resval.rstring);
/* Advance to next argument */
rb = rb->rbnext;
/* Get file attribute mask */
if (rb->restype != RTSHORT) {
ads_printf("\nDT_DOSDIR called with a %d type.", rb->restype);
ads_printf("\nExpected an integer as second argument.");
free(wildspec); /* free the string */
return RTERROR;
}
/* Save the value in local */
mask = rb->resval.rint;
/* Check for too many arguments */
if (rb->rbnext != NULL) {
ads_printf("\nDT_DOSDIR: Too many arguments.");
free (wildspec); /* free the string */
return RTERROR;
}
/* Get first filename from current directory */
retval = _dos_findfirst(wildspec, mask, &c_file);
retlist = NULL;
rettail = NULL;
while (retval == 0) {
rb = ads_newrb(RTSTR); /* allocate new buffer */
if (retlist == NULL) /* new return list? */
rettail = retlist = rb; /* they're all the same */
else { /* else, point current tail to */
rettail->rbnext = rb; /* new resbuf and then set tail*/
rettail = rb; /*equal to new resbuf */
}
rb->resval.rstring = strdup(c_file.name); /* store filename in list */
retval = _dos_findnext(&c_file); /* get next filename */
}
/* Now set up to return the list */
ads_retlist(retlist);
ads_relrb(retlist);
free (wildspec); /* free the string */
return RTNORM;
}
/* dt_doscurdrv assumes we will always be able to get the current drive
by calling _dos_getdrive(). There is no error checking. It returns
the drive number as an integer to AutoLISP.
getargs argument is a pointer to the first result buffer returned by
ads_getargs(). We expect to find no values in the resbuf chain. */
int dt_doscurdrv(getargs)
struct resbuf *getargs;
{
unsigned drive; /* current drive */
if (getargs != NULL) {
ads_printf("\nDT_DOSCURDRV: Too many arguments.");
return RTERROR;
}
_dos_getdrive(&drive);
/* Now return the drive as an integer */
ads_retint(drive);
return RTNORM;
}
/* Sets new current drive. Returns new drive as integer to AutoLISP.
getargs argument is a pointer to the first result buffer returned by
ads_getargs(). We expect to find one value in the resbuf chain: an
integer corresponding to the drive that we make current. */
int dt_dossetdrv(getargs)
struct resbuf *getargs;
{
unsigned newdrive; /* drive argument from user */
unsigned olddrive; /* drive before attempt to change */
unsigned curdrive; /* drive after attempt to change */
unsigned number_of_drives; /* required by _dos_setdrive() */
if (getargs == NULL) {
ads_printf("\nDT_DOSSETDRV: Expected an argument.");
return RTERROR;
}
if (getargs->restype != RTSHORT) {
ads_printf("\nDT_DOSSETDRV called with a %d type.", getargs->restype);
ads_printf("\nExpected an integer.");
return RTERROR;
}
newdrive = getargs->resval.rint; /* get argument from user */
_dos_getdrive(&olddrive); /* store old drive */
_dos_setdrive(newdrive, &number_of_drives); /* set to user's request */
_dos_getdrive(&curdrive); /* get current drive */
if (curdrive != newdrive) { /* if current drive not */
_dos_setdrive(olddrive, &number_of_drives); /* user's request, then */
ads_retnil(); /* restore old drive */
return RTNORM; /* and return nil, else */
}
ads_retint(curdrive); /* return new drive */
return RTNORM;
}
/* Returns the list of available drives to AutoLISP as a list of integers.
getargs argument is a pointer to the first result buffer returned by
ads_getargs(). We expect to find no values in the resbuf chain. */
int dt_dosdrv(getargs)
struct resbuf *getargs;
{
unsigned drive; /* loop variable for drive */
unsigned set_drive;
unsigned olddrive; /* store current drive */
unsigned number_of_drives; /* required by _dos_setdrive() */
struct resbuf *retlist, *rettail; /* return list */
struct resbuf *rb;
if (getargs != NULL) {
ads_printf("\nDT_DOSDRV: Too many arguments.");
return RTERROR;
}
/* Save current drive */
_dos_getdrive(&olddrive);
retlist = NULL;
rettail = NULL;
for (drive = 1; drive <= 26; drive++) { /* 26 drives possible in DT_DOS */
_dos_setdrive (drive, &number_of_drives);
_dos_getdrive (&set_drive);
if (set_drive == drive) { /* if we can set to it, */
/* then the drive exists */
rb = ads_newrb(RTSHORT);
if (retlist == NULL)
rettail = retlist = rb;
else {
rettail->rbnext = rb;
rettail = rb;
}
rb->resval.rint = drive; /* add it to the return list */
}
}
/* Restore old drive */
_dos_setdrive(olddrive, &number_of_drives);
/* Now set up to return the list */
ads_retlist(retlist);
ads_relrb(retlist);
return RTNORM;
}
/* Sets the current directory and returns the current directory to AutoLISP
as a string.
getargs argument is a pointer to the first result buffer returned by
ads_getargs(). We expect to find one argument in the resbuf chain: a
string for the directory that we make current. */
int dt_dossetdir(getargs)
struct resbuf *getargs;
{
char *dirname; /* local for dir arg from user */
if (getargs == NULL) {
ads_printf("\nDT_DOSSETDIR: Expected an argument.");
return RTERROR;
}
if (getargs->restype != RTSTR) {
ads_printf("\nDT_DOSSETDIR called with a %d type.", getargs->restype);
ads_printf("\nExpected a string.");
return RTERROR;
}
/* Store the directory in local */
dirname = strdup(getargs->resval.rstring);
if (chdir(dirname)) { /* if the call failed, then return nil */
free(dirname); /* free the string */
ads_retnil();
return RTNORM;
}
ads_retstr(dirname); /* return the directory that we set to */
free(dirname); /* free the string */
return RTNORM;
}
/* dt_doscurdir assumes that we will always be able to get the current
directory with a _getcwd() call. There's no error checking.
Returns the current directory as a string to AutoLISP.
getargs argument is a pointer to the first result buffer returned by
ads_getargs(). We expect to find no values in the resbuf chain. */
int dt_doscurdir(getargs)
struct resbuf *getargs;
{
char buffer[MAX_DIR]; /* Buffer for maximum directory string */
if (getargs != NULL) {
ads_printf("\nDT_DOSCURDIR: Too many arguments.");
return RTERROR;
}
if ((getcwd(buffer, MAX_DIR)) == NULL) { /* get the current directory */
free(buffer); /* if we fail, free the */
ads_retnil(); /* string and return nil */
return RTNORM;
}
ads_retstr(buffer); /* return the directory */
free(buffer); /* free the string */
return RTNORM;
}
/* Deletes a file.
getargs argument is a pointer to the first result buffer returned by
ads_getargs(). We expect to find one value in the resbuf chain: a
string corresponding to the filename we will delete. */
int dt_dosdeletefile(getargs)
struct resbuf *getargs;
{
struct resbuf *rb = NULL; /* temp resbuf for args */
char *filespec = NULL; /* initialize filename spec */
/* Get the arguments passed in with the function */
if (getargs == NULL) {
ads_printf("\nDT_DOSDELETEFILE: Expected argument.");
return RTERROR;
}
rb = getargs;
/* Get file specification */
if (rb->restype != RTSTR) {
ads_printf("\nDT_DOSDELETEFILE called with a %d type.", rb->restype);
ads_printf("\nExpected a string.");
return RTERROR;
}
/* Save the value in local */
filespec = strdup(rb->resval.rstring);
/* Check for too many arguments */
if (rb->rbnext != NULL) {
ads_printf("\nDT_DOSDELETEFILE: Too many arguments.");
free(filespec); /* free the string */
return RTERROR;
}
if (remove(filespec) == -1) { /* if we can't remove it */
ads_retnil(); /* return nil and */
free(filespec); /* free the string */
return RTNORM;
}
ads_retstr(filespec); /* return the deleted filename */
free(filespec); /* free the string */
return RTNORM;
}
/* DT_DOSRENAME function is used to rename a file to another specified name
the function takes as two arguments two file names or two paths to file
names. Path names must conform to proper dos paths. The two arguments
are used to rename a file. The 1st arg. is the file to rename and the
2nd arg. is the name to rename the file to. The function returns a 1 if
successful and a 0 if failed.
*/
int dt_dosrename(getargs)
struct resbuf *getargs;
{
char *fileold,*filenew;
int retval;
if(getargs == NULL) /* if no arguments passed */
{
ads_printf("\nDT_DOSRENAME: Expected an argument.");
return RTERROR; /* if no args return an error */
}
if(getargs->restype != RTSTR) /* if passed arg is not string return error */
{
ads_printf("\nDT_DOSRENAME: Called with a %d type.",getargs->restype);
ads_printf("\n1st parameter expected a string argument.");
return RTERROR;
}
if(getargs->rbnext->restype != RTSTR) /* if passed arg is not string return error */
{
ads_printf("\nDT_DOSRENAME: Called with a %d type.",getargs->restype);
ads_printf("\n2nd parameter expected a string argument.");
return RTERROR;
}
if(getargs->rbnext->rbnext != NULL) /* if too many arguments */
{
ads_printf("\nDT_DOSRENAME: Called with two many arguments.");
return RTERROR;
}
/* copy file path specs into temporay variables */
fileold = strdup(getargs->resval.rstring);
filenew = strdup(getargs->rbnext->resval.rstring);
retval = rename(fileold,filenew); /* rename file to new path */
free(fileold); /* free temporary storage for file specs */
free(filenew);
if(retval == 0)
{
ads_retint(1);
}
else
{
ads_retint(0);
}
return RTNORM;
}
char *str_toup(char *string)
{
int index;
/* process string until null character found */
for(index = 0; *(string + index) != '\0';++index)
{
if( isalpha(*(string + index)) ) /* if alphabetic proceed */
{
*(string + index) = toupper(*(string + index));
/* if lower convert it, else leave alone */
}
}
return string; /* return a pointer to the string */
}
char *str_tolow(char *string)
{
int index;
/* process string until null character found */
for(index = 0; *(string + index) != '\0';++index)
{
if( isalpha(*(string + index)) ) /* if alphabetic proceed */
{
*(string + index) = tolower(*(string + index));
/* if upper convert it, else leave alone */
}
}
return string; /* return a pointer to the string */
}